#include "filelistordermanager.h"
#include "fileidentitymanager.h"
#include <QDebug>
#include <QFileInfo>
#include <QCryptographicHash>

FileListOrderManager::FileListOrderManager(QObject* parent)
    : QObject(parent)
    , m_nextOriginalOrder(0)
{
}

void FileListOrderManager::setFiles(const QList<UnifiedFileInfo>& files)
{

    m_orderedFiles.clear();
    m_stableIdToIndex.clear();
    m_nextOriginalOrder = 0;

    for (const auto& file : files) {
        addFile(file);
    }

    rebuildIndexMaps();
    emit orderChanged();
}

void FileListOrderManager::addFile(const UnifiedFileInfo& file)
{
    FileOrderEntry entry;
    entry.fileInfo = file;
    entry.stableId = generateStableId(file);
    entry.originalOrder = m_nextOriginalOrder++;
    entry.lastModified = QDateTime::currentMSecsSinceEpoch();

    m_orderedFiles.append(entry);
    rebuildIndexMaps();

}

// === Martin Fowler: 类型安全的 removeFile 实现 ===
void FileListOrderManager::removeFile(const FileListIndex& index)
{

    if (!index.isValidFor(m_orderedFiles.size())) {
        return;
    }

    int safeIndex = index.safeValue(m_orderedFiles.size());
    QString removedId = m_orderedFiles[safeIndex].stableId;
    m_orderedFiles.removeAt(safeIndex);
    rebuildIndexMaps();

    emit orderChanged();
}


// === Martin Fowler: 类型安全的 moveFiles 实现 ===
void FileListOrderManager::moveFiles(const FileListIndexRange& fromIndices, const FileListIndex& toIndex)
{

    // 使用 FileListIndex 进行验证
    if (fromIndices.isEmpty() || !toIndex.isValidInsertPositionFor(m_orderedFiles.size())) {
        return;
    }

    // 验证所有索引都有效 - 详细调试信息
    QList<int> debugIndices = fromIndices.rawIndices();
    for (int idx : debugIndices) {
        FileListIndex checkIndex = FileListIndex::at(idx);
        bool valid = checkIndex.isValidFor(m_orderedFiles.size());
    }

    if (!fromIndices.allValidFor(m_orderedFiles.size())) {
        return;
    }


    // 获取安全的原始索引列表
    QList<int> rawIndices = fromIndices.safeIndices(m_orderedFiles.size());
    int rawToIndex = toIndex.safeInsertPosition(m_orderedFiles.size());

    // 按倒序排序，避免删除时索引变化
    std::sort(rawIndices.begin(), rawIndices.end(), std::greater<int>());

    // 提取要移动的文件
    QList<FileOrderEntry> movedFiles;
    int originalToIndex = rawToIndex;

    for (int index : rawIndices) {
        FileListIndex safeIndex = FileListIndex::at(index);
        if (safeIndex.isValidFor(m_orderedFiles.size())) {
            movedFiles.prepend(m_orderedFiles[index]);  // 保持原顺序
            m_orderedFiles.removeAt(index);

            // 调整目标索引：如果移除的元素在目标位置之前，目标位置需要前移
            if (index < originalToIndex) {
                rawToIndex = qMax(0, rawToIndex - 1);
            }

        } else {
        }
    }


    // 在目标位置插入，使用 FileListIndex 进行安全计算
    FileListIndex insertIndex = FileListIndex::at(rawToIndex);
    int safeInsertIndex = insertIndex.safeInsertPosition(m_orderedFiles.size());

    for (int i = 0; i < movedFiles.size(); ++i) {
        FileListIndex finalInsertIndex = FileListIndex::at(safeInsertIndex + i);
        int safeFinalIndex = finalInsertIndex.safeInsertPosition(m_orderedFiles.size());
        m_orderedFiles.insert(safeFinalIndex, movedFiles[i]);
    }


    // 更新时间戳以保持稳定性
    maintainOrderStability();
    rebuildIndexMaps();

    emit orderChanged();
}


QList<UnifiedFileInfo> FileListOrderManager::getStableOrderedFiles() const
{
    QList<UnifiedFileInfo> result;
    for (const auto& entry : m_orderedFiles) {
        result.append(entry.fileInfo);
    }
    return result;
}

// === Martin Fowler: 类型安全的索引映射方法 ===
FileListIndex FileListOrderManager::mapOriginalToCurrentIndex(const FileListIndex& originalIndex) const
{

    if (!originalIndex.isValid()) {
        return FileListIndex::invalid();
    }

    int originalValue = originalIndex.value();
    for (int i = 0; i < m_orderedFiles.size(); ++i) {
        if (m_orderedFiles[i].originalOrder == originalValue) {
            FileListIndex result = FileListIndex::at(i);
            return result;
        }
    }

    return FileListIndex::invalid();
}

FileListIndex FileListOrderManager::mapCurrentToOriginalIndex(const FileListIndex& currentIndex) const
{

    if (!currentIndex.isValidFor(m_orderedFiles.size())) {
        return FileListIndex::invalid();
    }

    int safeCurrentIndex = currentIndex.safeValue(m_orderedFiles.size());
    int originalOrder = m_orderedFiles[safeCurrentIndex].originalOrder;
    FileListIndex result = FileListIndex::at(originalOrder);
    return result;
}


void FileListOrderManager::onLayoutChanged(const QString& fileIdentity, LayoutMode mode)
{

    // 布局变更不影响排序，但需要验证一致性
    if (!verifyConsistency()) {
        emit consistencyIssueDetected("布局变更后文件顺序不一致");
    }
}

void FileListOrderManager::onBatchLayoutChanged()
{

    // 批量变更后强制重建索引映射
    rebuildIndexMaps();

    if (!verifyConsistency()) {
        emit consistencyIssueDetected("批量布局变更后文件顺序不一致");
        // 尝试恢复稳定性
        maintainOrderStability();
        rebuildIndexMaps();
    }
}

bool FileListOrderManager::verifyConsistency() const
{
    // 验证索引映射的一致性
    if (m_orderedFiles.size() != m_stableIdToIndex.size()) {
        return false;
    }

    // 验证稳定ID的唯一性
    QSet<QString> seenIds;
    for (const auto& entry : m_orderedFiles) {
        if (seenIds.contains(entry.stableId)) {
            return false;
        }
        seenIds.insert(entry.stableId);
    }

    return true;
}

QString FileListOrderManager::getFileIdentityAt(int index) const
{
    if (index >= 0 && index < m_orderedFiles.size()) {
        return FileIdentityManager::getFileIdentity(m_orderedFiles[index].fileInfo.filePath);
    }
    return QString();
}

void FileListOrderManager::rebuildIndexMaps()
{
    m_stableIdToIndex.clear();
    for (int i = 0; i < m_orderedFiles.size(); ++i) {
        m_stableIdToIndex[m_orderedFiles[i].stableId] = i;
    }

}

QString FileListOrderManager::generateStableId(const UnifiedFileInfo& file) const
{
    // 基于文件路径生成稳定的ID
    QByteArray data = file.filePath.toUtf8();
    QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
    return QString(hash.toHex());
}

void FileListOrderManager::maintainOrderStability()
{

    // 更新所有文件的修改时间戳
    qint64 currentTime = QDateTime::currentMSecsSinceEpoch();
    for (auto& entry : m_orderedFiles) {
        entry.lastModified = currentTime++;
    }
}